#pragma once
#include "gtest/gtest.h"

#include "DataStructure/Input/Element/CQUAD4Data.h"
#include "TestData/model/Link_EvenTwentyTruss.hpp"
#include "TestData/model/Link_TwentyTruss.hpp"
#include "TestData/model/Quad4_FourQuad.hpp"
#include "TestData/model/Quad4_FourQuadDisc.hpp"

#include "../DOFHandler.h"
#include "../GeneratePartition.h"
#include "Utility/Configuration/SGConfig.h"

using SG::Algebra::Graph;
using SG::DataStructure::FEM::CQUAD4Data;
using SG::FEMSolver::DOFHandler;
using SG::FEMSolver::GeneratePartitioning;

TEST (GeneratePartitionTest, Quad4_FourQuadCase)
{
    // Input
    Quad4_FourQuad model;
    auto           dbServiceFactory = model.GetModel ();
    auto           nodeIds          = dbServiceFactory->get<INodeService> ()->GetAllId ();
    auto           elementIds       = dbServiceFactory->get<IElementService> ()->GetAllId<CQUAD4Data> ();
    auto           elementNodeIds   = dbServiceFactory->get<IElementService> ()->GetElementNodes (ElementTypes::ELETYPE_ShellQuad4);

    // Test data
    SG::Utility::SGParameter parameters = SG::Utility::SGConfig::GetInstance ().GetData ().GetValue ("Partition");

    // parameters["NParts"] = 2;
    // int nparts           = parameters.GetValue ("NParts").GetInt ();

    SG::DataStructure::Common::IdArray SGPartitionElement;
    SG::DataStructure::Common::IdArray SGPartitionElementTest (4);
    SGPartitionElementTest[0] = 0;
    SGPartitionElementTest[1] = 0;
    SGPartitionElementTest[2] = 1;
    SGPartitionElementTest[3] = 1;

    GeneratePartitioning::SGPartitioner (dbServiceFactory, nodeIds, elementIds, elementNodeIds, parameters, SGPartitionElement);
    ASSERT_TRUE (SGPartitionElement == SGPartitionElementTest);
}

TEST (GeneratePartitionTest, Quad4_FourQuadDiscCase)
{
    // Input
    Quad4_FourQuadDisc model;
    auto           dbServiceFactory = model.GetModel ();
    auto           nodeIds          = dbServiceFactory->get<INodeService> ()->GetAllId ();
    auto           elementIds       = dbServiceFactory->get<IElementService> ()->GetAllId<CQUAD4Data> ();
    auto           elementNodeIds   = dbServiceFactory->get<IElementService> ()->GetElementNodes (ElementTypes::ELETYPE_ShellQuad4);

    // Test data
    SG::Utility::SGParameter parameters = SG::Utility::SGConfig::GetInstance ().GetData ().GetValue ("Partition");

    // parameters["nparts"] = 2;
    // int nparts           = parameters.GetValue ("nparts").GetInt ();

    SG::DataStructure::Common::IdArray SGPartitionElement;
    SG::DataStructure::Common::IdArray SGPartitionElementTest1 (4);
    SGPartitionElementTest1[0] = 0;
    SGPartitionElementTest1[1] = 1;
    SGPartitionElementTest1[2] = 1;
    SGPartitionElementTest1[3] = 0;
    SG::DataStructure::Common::IdArray SGPartitionElementTest2 (4);
    SGPartitionElementTest2[0] = 1;
    SGPartitionElementTest2[1] = 0;
    SGPartitionElementTest2[2] = 0;
    SGPartitionElementTest2[3] = 1;

    GeneratePartitioning::SGPartitioner (dbServiceFactory, nodeIds, elementIds, elementNodeIds, parameters, SGPartitionElement);
    ASSERT_TRUE (SGPartitionElement == SGPartitionElementTest1 || SGPartitionElement == SGPartitionElementTest2);
}